package cn.finder.datatunnel.processor;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;

import org.apache.log4j.Logger;

import cn.finder.datatunnel.DTConfig;
import cn.finder.datatunnel.DTException;
import cn.finder.datatunnel.DTUtils;
import cn.finder.datatunnel.HttpUtils;

/***
 * 默认处理客户端发来的数据 
 * 该处理机制为：  完全转发功能， 把客户端发送过来的数据 完全一样发送到转发端口
 * @author whl
 *
 */
public  class DefaultProcessor implements Processor{

	private static Logger logger=Logger.getLogger(DefaultProcessor.class);
	
	protected DataChannel dataChannel;
	
	/***
	 * 表示该什么周期是否继续  或者 数据继续往下传递
	 */
	private boolean chain=true;
	
	public void setChain(boolean chain){
		this.chain=chain;
	}
	public boolean getChain() {
		return chain;
	}
	
	
	public DefaultProcessor(){
		
	}
	
	public byte[] read() throws DTException, IOException {
		byte[] readData=null;
		if(dataChannel instanceof TcpDataChannel){
			TcpDataChannel tcpDataChannel=(TcpDataChannel)dataChannel;
			InputStream is=tcpDataChannel.getChannel().getInputStream();
			readData= DTUtils.streamToBytes(is);
			
		}else if(dataChannel instanceof UdpDataChannel){
			UdpDataChannel udpDataChannel=(UdpDataChannel)dataChannel;
			readData=DTUtils.readToBytes(udpDataChannel);
		}
		
		logger.debug("===DefaultProcessor.read:"+new String(readData));
		
		return readData;
	}

	public String write(byte[] data) throws DTException, IOException {
		
		if(data==null){
			data=new byte[0];
		}
		
		
		logger.debug("======write:"+new String(data));
		
	   if("tcp".equalsIgnoreCase(DTConfig.dt_client_read_protocol)){
		   //如果客户端是tcp连接
		   OutputStream clientOS= ((TcpDataChannel)dataChannel).getChannel().getOutputStream();
		   DataOutputStream out = new DataOutputStream(clientOS);
		   out.write(data);
		   out.flush();
			   
	   }
	   else if("udp".equalsIgnoreCase(DTConfig.dt_client_read_protocol)){
		   //如果客户端是udp连接, 构建新的socket发送
		   int dt_client_send_port=-1;
		   try{
			   try{
				   dt_client_send_port= Integer.parseInt(DTConfig.dt_client_send_port);
				   
			   }
			   catch(Exception e){
				   dt_client_send_port=-1;
			   }
			   
			   if(dt_client_send_port!=-1){
				  /* Socket sendClientSocket=new Socket(((TcpDataChannel)dataChannel).getSocket().getInetAddress(),dt_client_send_port);
				   OutputStream  sendClientSocketOS=sendClientSocket.getOutputStream();
				   
				   DataOutputStream out = new DataOutputStream(sendClientSocketOS);
				   out.write(data);
				   out.flush();
				   out.close();*/
				   UdpDataChannel udpDataChannel=(UdpDataChannel)dataChannel;
				   InetAddress clientHostAddress= udpDataChannel.getDatagramPacket().getAddress();
				   
				  // DatagramSocket dataSocket = new DatagramSocket(0); 0使用本地随机端口发送  
				   DatagramPacket dataPacket = new DatagramPacket(data, data.length,
						   clientHostAddress, dt_client_send_port);
				   try{
					   udpDataChannel.getChannel().send(dataPacket); //此处还是用 之前绑定的端口
				   }
		           finally{
		        	   //udpDataChannel.getChannel().close(); 
		        	   //dataSocket.disconnect();
		           }
		        	  
		           
		           
		           
			   }
			   
			   
		   }
		   catch(Exception e){
			   logger.error(e);
		   }
		   
	   }
		return null;
	}

	public byte[]  send(byte[] data) throws DTException, IOException {
		
		
		logger.debug("===DefaultProcessor.send:"+new String(data));
		
		if("udp".equalsIgnoreCase(DTConfig.dt_server_send_protocol)){
			//通过socket发送到服务器
			/*Socket socket2=new Socket(DTConfig.dt_server_send_address, Integer.valueOf(DTConfig.dt_server_listen_port).intValue());
			OutputStream os=socket2.getOutputStream();
			
			os.write(data);
		    os.flush();
		    os.close();
		    socket2.close();*/
			
			
			
			DatagramSocket dataSocket = new DatagramSocket(0);
		    DatagramPacket dataPacket = new DatagramPacket(data, data.length,
		    		InetAddress.getByName(DTConfig.dt_server_send_address), Integer.valueOf(DTConfig.dt_server_listen_port).intValue());
            dataSocket.send(dataPacket);
            
            dataSocket.close();
            
			
		}
		else if("tcp".equalsIgnoreCase(DTConfig.dt_server_send_protocol)){
			Socket socket2=new Socket(DTConfig.dt_server_send_address, Integer.valueOf(DTConfig.dt_server_listen_port).intValue());
			OutputStream os=socket2.getOutputStream();
			
			
			os.write(data);
		    os.flush();
		    
		    
		   InputStream is=socket2.getInputStream();
		   byte[] bytes=DTUtils.streamToBytes(is);
		   logger.debug("======send ==>read srv data:"+new String(bytes));
		   is.close();
		   os.close();
		   socket2.close();
		   
		   return bytes;
		}
		else if("http".equalsIgnoreCase(DTConfig.dt_server_send_protocol)){
			
			HttpUtils httpUtils=new HttpUtils();
			String retStr=httpUtils.doPostData(DTConfig.dt_server_send_address, new String(data));
			//logger.debug("======http return:"+new String(retStr.getBytes("UTF-8")));
			return retStr.getBytes("UTF-8");
		}
		
		return null;
	}
	


	public void setDataChannel(DataChannel dataChannel) {
		this.dataChannel=dataChannel;
	}

	public byte[] afterRead(byte[] data) {
		// TODO Auto-generated method stub
		return data;
	}

	public byte[] beforeSend(byte[] data) {
		// TODO Auto-generated method stub
		return data;
	}

	public byte[] afterSend(byte[] data) {
		// TODO Auto-generated method stub
		return data;
	}

	public byte[] beforeWrite(byte[] data) {
		// TODO Auto-generated method stub
		return data;
	}

	public String afterWrite(String value) {
		// TODO Auto-generated method stub
		return value;
	}

	public DTException occurException(Throwable e) {
		
		return null;
	}



	



}
